# 导入必要的库
from flask import Flask, request, jsonify  # Flask核心功能
from flask_sqlalchemy import SQLAlchemy  # ORM数据库操作
from flask_migrate import Migrate  # 数据库迁移
from flask_cors import CORS  # 跨域支持
from flask_jwt_extended import (  # JWT认证
    JWTManager, create_access_token, jwt_required, get_jwt_identity
)
from werkzeug.security import generate_password_hash, check_password_hash  # 密码加密验证
from datetime import timedelta  # 时间处理
import os  # 系统操作

# 初始化Flask应用
app = Flask(__name__)
CORS(app)  # 启用跨域支持

# 应用配置
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'  # SQLite数据库路径
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False  # 禁用SQLAlchemy事件系统
app.config['JWT_SECRET_KEY'] = os.getenv('JWT_SECRET', 'your-secret-key')  # JWT密钥
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(hours=1)  # Token有效期1小时

# 初始化扩展
db = SQLAlchemy(app)  # 数据库实例
migrate = Migrate(app, db)  # 数据库迁移
jwt = JWTManager(app)  # JWT管理

# 数据模型定义
class User(db.Model):
    """用户模型"""
    id = db.Column(db.Integer, primary_key=True)  # 用户ID
    username = db.Column(db.String(80), unique=True, nullable=False)  # 用户名
    password_hash = db.Column(db.String(120), nullable=False)  # 密码哈希
    todos = db.relationship('Todo', backref='user', lazy=True)  # 与Todo的一对多关系

class Todo(db.Model):
    """Todo项模型"""
    id = db.Column(db.Integer, primary_key=True)  # Todo ID
    title = db.Column(db.String(120), nullable=False)  # 标题
    description = db.Column(db.Text)  # 描述
    completed = db.Column(db.Boolean, default=False)  # 完成状态
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)  # 外键关联用户

# API路由定义
@app.route('/api/register', methods=['POST'])
def register():
    """用户注册接口"""
    data = request.get_json()  # 获取请求数据
    username = data.get('username')  # 用户名
    password = data.get('password')  # 密码

    # 检查用户名是否已存在
    if User.query.filter_by(username=username).first():
        return jsonify({'message': '用户名已存在'}), 400

    # 创建新用户
    user = User(
        username=username,
        password_hash=generate_password_hash(password)  # 密码加密存储
    )
    db.session.add(user)
    db.session.commit()

    return jsonify({'message': '用户创建成功'}), 201

@app.route('/api/login', methods=['POST'])
def login():
    """用户登录接口"""
    data = request.get_json()  # 获取请求数据
    username = data.get('username')  # 用户名
    password = data.get('password')  # 密码

    # 验证用户
    user = User.query.filter_by(username=username).first()
    if not user or not check_password_hash(user.password_hash, password):
        return jsonify({'message': '用户名或密码错误'}), 401

    # 生成JWT Token
    token = create_access_token(identity=user.id)
    return jsonify({'token': token}), 200

@app.route('/api/todos', methods=['GET'])
@jwt_required()
def get_todos():
    """获取当前用户的Todo列表"""
    user_id = get_jwt_identity()  # 从Token获取用户ID
    todos = Todo.query.filter_by(user_id=user_id).all()  # 查询当前用户的Todo
    return jsonify([{
        'id': todo.id,
        'title': todo.title,
        'description': todo.description,
        'completed': todo.completed
    } for todo in todos]), 200

@app.route('/api/todos', methods=['POST'])
@jwt_required()
def create_todo():
    """创建新的Todo"""
    user_id = get_jwt_identity()  # 从Token获取用户ID
    data = request.get_json()  # 获取请求数据
    todo = Todo(
        title=data['title'],  # 标题
        description=data.get('description', ''),  # 描述（可选）
        user_id=user_id  # 关联用户
    )
    db.session.add(todo)
    db.session.commit()
    return jsonify({
        'id': todo.id,
        'title': todo.title,
        'description': todo.description,
        'completed': todo.completed
    }), 201

@app.route('/api/todos/<int:todo_id>', methods=['PUT'])
@jwt_required()
def update_todo(todo_id):
    """更新Todo"""
    user_id = get_jwt_identity()  # 从Token获取用户ID
    todo = Todo.query.filter_by(id=todo_id, user_id=user_id).first()  # 查找Todo
    if not todo:
        return jsonify({'message': 'Todo未找到'}), 404

    # 更新Todo信息
    data = request.get_json()
    todo.title = data.get('title', todo.title)
    todo.description = data.get('description', todo.description)
    todo.completed = data.get('completed', todo.completed)
    db.session.commit()
    return jsonify({
        'id': todo.id,
        'title': todo.title,
        'description': todo.description,
        'completed': todo.completed
    }), 200

@app.route('/api/todos/<int:todo_id>', methods=['DELETE'])
@jwt_required()
def delete_todo(todo_id):
    """删除Todo"""
    user_id = get_jwt_identity()  # 从Token获取用户ID
    todo = Todo.query.filter_by(id=todo_id, user_id=user_id).first()  # 查找Todo
    if not todo:
        return jsonify({'message': 'Todo未找到'}), 404

    db.session.delete(todo)
    db.session.commit()
    return jsonify({'message': 'Todo已删除'}), 200

# 启动应用
if __name__ == '__main__':
    app.run(debug=False)  # 生产模式运行
